
#include "defines.h"
#include "video/Node.h"
#include <assert.h>
#include "video/NameGenerator.h"

namespace KEngine
{
	Node::Node():_parent(0)
	{
		_name = NameGenerator::getSingleton().generateNodeName();
	}

	Node::Node(const std::string& name):_name(name),_parent(0)
	{

	}

	Node::~Node()
	{

	}

	const std::string& Node::getName() const
	{
		return _name;
	}
	void Node::setName(const std::string& name)
	{
		_name = name;
	}
	const Node* Node::getParent() const
	{
		return _parent;
	}
	void Node::setParent(Node* parent)
	{
		_parent = parent;
	}

	void Node::addChild(Node* child)
	{
		assert(child->_parent == NULL);

		_children.insert(ChildNodeValue(child->getName(), child));
		child->setParent(this);
	}
	unsigned int Node::numChildren() const
	{
		return _children.size();
	}

	
	Node* Node::getChild(unsigned int index) const
	{
		if (index < _children.size())
		{
			ChildNodeConstIterator i = _children.begin();
			while (--index)
				++i;
			return i->second;
		}
		else
			return 0;
	}
	Node* Node::getChild(std::string& name) const
	{
		ChildNodeConstIterator i = _children.find(name);
		if (i == _children.end())
			return 0;
		else
			return i->second;
	}
	Node* Node::removeChild(unsigned int index)
	{
		if (index < _children.size())
		{
			ChildNodeIterator i = _children.begin();
			while (index--) ++i;	
			Node* ret = i->second;

			_children.erase(i);
			ret->setParent(NULL);
			return ret;
		}
		else
			assert(0);

		return 0;
	}
	Node* Node::removeChild(Node* child)
	{
		if (child)
		{
			ChildNodeIterator i = _children.find(child->getName());
			// ensure it's our child
			if (i != _children.end() && i->second == child)
			{
				_children.erase(i);
				child->setParent(0);
			}
		}

		return child;
	}
	Node* Node::removeChild(std::string& name)
	{
		ChildNodeIterator i = _children.find(name);
		if (i != _children.end())
		{
			Node* ret = i->second;
			_children.erase(i);
			ret->setParent(0);

			return ret;
		}

		return 0;
	}
	void Node::removeAllChildren()
	{
		ChildNodeIterator i, iend;
		iend = _children.end();
		for (i = _children.begin(); i != iend; ++i)
		{
			i->second->setParent(NULL);
		}
		_children.clear();
	}
	void Node::destroy()
	{
		ChildNodeIterator i, iend;
		iend = _children.end();
		for (i = _children.begin(); i != iend; ++i)
		{
			i->second->destroy();
			KSafeDelete(i->second);
		}
		_children.clear();
	}
	
};
